Lambdaの設計図からAPI GatewayのHTTP APIを作成する時にはペイロード形式のバージョンに注意

Lambdaの設計図からAPI GatewayのHTTP APIを作成する時にはペイロード形式のバージョンに注意

AWS Lambda実践ガイド 第2版を参考にLambdaとの設計図からAPI Gatewayを作成していたら、予期しないInternal Server Errorに困った話です
Clock Icon2022.09.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、AWS事業本部コンサルティング部に所属している今泉(@bun76235104)です。

今回は私がLambdaとAPI GatewayのHTTPエンドポイントを利用していた際に、少しハマってしまった点について紹介させていただきます。

結論

  • Lambdaを設計図から作成した際に、API GatewayのHTTP APIのペイロード形式が1.0で作成されていた
    • デフォルトでペイロード形式が2.0で作成されると思い込んでいた
  • Lambda関数の戻り値がペイロード形式2.0で利用できるが、1.0では利用できない形式だった
  • そのためInternal Server Errorが返却されてしまった

Lambdaの設計図からAPI Gatwayを合わせて作成した

以下の書籍(AWS Lambda実践ガイド 第2版)で学習したことを参考に、microservice-http-endpoint-pythonの設計図(Blueprint)を利用して、簡単なAPIを作成しておりました。

書籍の手順に従って、設計図からLambdaとAPI GatewayなどのリソースをAWSマネジメントコンソールのLambdaの画面で作成していました。

  • 設計図(microservice-http-endpoint-python)からLambdaを作成開始

lambda_create_from_bluprint

  • API GatewayをHTTP APIを指定して作成

create_api_gateway

※ 検証用のため認証も入れないオープンなAPIにしています。同じように検証される際はAPIを長く残さないなどご留意ください。

  • Lambda関数のコードを以下のように修正してデプロイ
import json


def lambda_handler(event, context):
    print(json.dumps(event, indent=4))
    return json.dumps({})
  • Lambda関数からのテストで正常に動作することを確認(意図したどおりの出力値が返される)
"{}"

ここまで成功したので、APIゲートウェイのエンドポイントにブラウザからアクセスしてみると以下のようにレスポンスされます。

{"message":"Internal Server Error"}

HTTPのステータスコードも500となっており、正常にレスポンスができていないことがわかりました。

原因

LambdaとAPI GatewayのHTTP APIを利用する際には、Lambda関数は決まった形式で値を返す必要があります。

返却形式(以下ペイロード形式と表記)には本記事を執筆した時点でバージョン1.0と2.0があります。

バージョン1.0では以下の形式で必ずレスポンスを返す必要があります。

{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headername": "headervalue", ... },
    "multiValueHeaders": { "headername": ["headervalue", "headervalue2", ...], ... },
    "body": "..."
}

一方2.0ではパラメータの形式が上記の形式ではなくても、API Gatewayがレスポンス形式を推測できます。

以下のようにLambda関数で出力した場合、API Gatewayが良い形で解釈してくれるようです。

  • Lambda関数の出力
"Hello from Lambda!"
  • API Gatewayの解釈
{
  "isBase64Encoded": false,
  "statusCode": 200,
  "body": "Hello from Lambda!",
  "headers": {
    "content-type": "application/json"
  }
}

公式ドキュメントには以下のように記載があります。

ペイロード形式バージョンでは、API Gateway が Lambda 統合に送信するデータの形式と、API Gateway が Lambda からのレスポンスをどのように解釈するかを指定します。ペイロード形式バージョンを指定しない場合、AWS Management Console はデフォルトで最新バージョンを使用します。

これを「Lambda作成画面からAPI GatewayのHTTP APIを作成すると2.0がデフォルトで使われる」と誤って読解してしまいました。

これは「API Gatewayの作成画面から、統合機能を利用してLambdaを作成する際に2.0がデフォルトで利用される」というそのままの意味でした。

create_lambda_from_apigateway_console

※ 実際上記ページは「HTTP API の AWS Lambda プロキシ統合の使用」というタイトルで、API Gatewayのドキュメントです。なぜ勘違いしてしまったのか。

今回はLambdaの作成画面から設計図を使ってAPI GatewayのHTTP APIを作成したため、ペイロード形式のバージョンが1.0になっているようです。

created_api_gateway_from_blueprint

ということで、ペイロード形式のバージョンを2.0に変更することで、意図したレスポンスが返されるようになりました。

edited_payload_version

まとめ

Lambdaの画面からAPI Gatewayを作成した場合、ペイロード形式のバージョンは常に2.0になると思い込んでいました。

詳細については検証できておりませんが、皆さんもAPI GateWayのHTTP APIを利用する際には、ペイロード形式のバージョンにご留意ください。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.